<?php

namespace App\Models\Activity;

use App\Contracts\Repositories\ActivityRepository as ActivityRepositoryContract;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\SoftDeletes;

class ActivityRepository implements ActivityRepositoryContract
{
    use SoftDeletes;
    /**
     * {@inheritdoc}
     * @see \App\Contracts\Repositories\ActivityRepository::create()
     */
    public function create(Activity $activity)
    {
        if (!is_null($activity->getId())) {
            throw new \Exception('duplicate id');
        }
        if ($activity->save()) {
            return $activity;
        }

        return null;
    }

    /**
     * {@inheritdoc}
     * @see \App\Contracts\Repositories\ActivityRepository::findByUserId()
     */
    public function findByUserId($userId)
    {
        return Activity::query()->where('user_id', $userId)->orderBy('created_at', 'desc')->get();
    }

    /**
     * {@inheritdoc}
     * @see \App\Contracts\Repositories\ActivityRepository::findGroupActivityById()
     */
    public function findGroupActivityById($activityId, $groupCode)
    {
        return Activity::query()->where([['group_code', $groupCode],['id', $activityId]])->first();
    }

    /**
     * {@inheritdoc}
     * @see \App\Contracts\Repositories\ActivityRepository::findRunningByUserId()
     */
    public function findRunningByUserId($userId)
    {
        return Activity::query()->where([['user_id', $userId], ['isPause', 0], ['startTime', '<=', date('Y-m-d H:i:s')], ['endTime', '>=', date('Y-m-d H:i:s')]])->orderBy('created_at', 'desc')->get();
    }

    /**
     * {@inheritdoc}
     * @see \App\Contracts\Repositories\ActivityRepository::findRunningModel()
     */
    public function findRunningModel($model)
    {
        $query = Activity::query()
            ->where(['model_id' => $model, 'isPause' => 0])
            ->orderBy('created_at', 'desc');

        return $query->get();
    }

    public function getFinishedActivities()
    {
        $nowTime   = Carbon::now();
        $limitTime = Carbon::parse('-3 months')->toDateTimeString();
        $query = Activity::query()
            ->whereBetween('endTime',[$limitTime,$nowTime])
            ->get();
        return $query;
    }

    public function getFinishedActivitiesOneMonthsAgo(){
        $nowTime   = Carbon::parse('-1 months')->toDateTimeString();
        $limitTime = Carbon::parse('-4 months')->toDateTimeString();
        $query = Activity::query()->with('records')
            ->whereBetween('endTime',[$limitTime,$nowTime])
            ->get();
        return $query;
    }
    public function getDeletedActivitiesOneMonthAgo(){
        $nowTime   = Carbon::parse('-1 months')->toDateTimeString();
        $limitTime = Carbon::parse('-4 months')->toDateTimeString();
        $query = Activity::query()->with('records')
            ->whereBetween('deleted_at',[$limitTime,$nowTime])
            ->get();
        return $query;
    }

    /**
     * {@inheritdoc}
     * @see \App\Contracts\Repositories\ActivityRepository::findByGroupCode()
     */
    public function findByGroupCode($groupCode)
    {
        return Activity::query()
            ->where([['group_code', $groupCode], ['isPause', 0]])
            ->orderBy('weight', 'desc')
            ->orderBy('created_at', 'desc')
            ->get();
    }

    /**
     * {@inheritdoc}
     * @see \App\Contracts\Repositories\ActivityRepository::findByCategory()
     */
    public function findByCategory($groupCode, $category, $sort, $order, $start = 0, $limit = 10, $keyword = null)
    {
        $query = Activity::query()->with(['model', 'template'])
            ->where([
                'category'   => $category,
                'group_code' => $groupCode,
            ]);
        if (!is_null($keyword)) {
            $query->where('name', 'like', '%' . $keyword . '%');
        }
        $count = $query->count();
        $query->limit($limit)->skip($start);
        $query->orderBy($sort, $order);
        if($sort == 'weight'){
            $query->orderBy('created_at', 'desc');
        }
        return [$count, $query->get()];
    }

    public function countByConditions($condition)
    {
        $qb = Activity::query();

        return $qb->where($condition)->count();
    }

    public function update($updates, $conditions)
    {
        return Activity::query()->where($conditions)->update($updates);
    }

    public function delete($conditions)
    {
        // TODO: Implement delete() method.

        return Activity::query()->where($conditions)->delete();
    }

    public function deleteByIds($ids)
    {
        // TODO: Implement deleteByIds() method.

        return Activity::destroy($ids);
    }

    public function findOne($id, $columns = ['*'])
    {
        // TODO: Implement findOne() method.

        return Activity::query()->find($id, $columns);
    }

    /**
     * {@inheritdoc}
     * @see \App\Contracts\Repositories\ActivityRepository::findByTpl()
     */
    public function findByTpl($template_id, $field = null)
    {
        $nowTime = Carbon::now();

        return Activity::query()
            ->where('startTime', '<', $nowTime)
            ->where('endTime', '>', $nowTime)
            ->get(['id'])
            ->toArray();
    }

    /**
     * {@inheritdoc}
     * @see \App\Contracts\Repositories\ActivityRepository::findByModelOrUserId()
     */
    public function findByModelOrUserId($model, $userId = null)
    {
        $query = Activity::query();
        if (!is_null($userId)) {
            $query->where('user_id', $userId);
        }
        $query->where('model_id', $model);

        return $query->get();
    }

    public function findByModelIdInSameTenant($groupCode, $modelId, array $columns = ['*'])
    {
        return \App\Entities\Activity::query()
            ->where('group_code', $groupCode)
            ->where('model_id', $modelId)
            ->get($columns);
    }
}
